package edu.xalead.版本五;

import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Random;

import static sun.swing.MenuItemLayoutHelper.max;

public class Board {
    private maxminNode root = null;
    /*
    创建评分表
     */
    static final int[][] score = {
            { 0, 0,  0,  0,   0,10000 },//防守2子
            { 0, 0, 20,100, 500,10000 },//防守1子
            { 0,20,100,500,2500,10000 } //防守0子
    };

    //创建一个结点类
    class maxminNode{
        private Chess chess;//当前局面要下的棋子
        private char[][] core;//落子后的棋局
        private int score; //保存当前局面的估值函数值
        private maxminNode next;


        public maxminNode(Chess chess) {
            this.chess = chess;
        }

        public Chess getChess() {
            return chess;
        }

        public void setChess(Chess chess) {
            this.chess = chess;
        }

        public char[][] getCore() {
            return core;
        }

        public void setCore(char[][] core) {
            this.core = core;
        }

        public int getScore() {
            return score;
        }

        public void setScore(int score) {
            this.score = score;
        }

        public maxminNode getNext() {
            return next;
        }

        public void setNext(maxminNode next) {
            this.next = next;
        }

    }
    /*
    创建棋盘
     */
    public char[][] createBoard(){
        char[][] board = new char[19][19];

        for (int i=0;i<board.length;i++){

            for (int j=0;j<board.length;j++){

                board[i][j] = '+';
            }
        }
        return board;
    }
    /*
    棋盘展示方法
     */
    public void showBoard(char[][] board){
        System.out.print(" ");
        for (int ia=0;ia<board.length;ia++){
            System.out.print(" "+ia);
        }
        System.out.println();
        for (int i=0;i<board.length;i++){
            System.out.print(i);
            for (int j=0;j<board.length;j++){
                System.out.print(" "+board[i][j]);
            }
            System.out.println();
        }
    }

    /*
    判断是否获胜
     */
    public boolean judgeSuccess(char[][] board,int x,int y,char color){
        //水平
        int starty = y-4 < 0 ? 0:y-4;
        int endy = y+4 > board.length-1 ? board.length-1 : y+4 ;
        int startx = x-4 < 0 ? 0:x-4;
        int endx = x+4 > board.length-1 ? board.length-1 : x+4 ;
        int num = 0; //作为计数器使用

        for (int i=starty;i<=endy;i++){
            if (board[x][i]== color){
                num++;
            }else {num = 0;}
            if (num==5){
                return true;
            }
        }
        //竖直

        for (int i=startx;i<=endx;i++){
            if (board[i][y]==color){
                num++;
            }else {num = 0;}
            if (num==5){
                return true;
            }
        }
        //左倾斜
        int j=starty;
        for (int i=startx;i<=endx;i++){
            if (board[i][j]==color){
                num++;
            }else{num=0;}
            if (num==5){
                return true;
            }
            if (j!=endy)j++;
        }

        //右倾斜
        j=endy;
        for (int i=startx;i<=endx;i++){
            if (board[i][j]==color){
                num++;
            }else{num=0;}
            if (num==5){
                return true;
            }
            if (j!=0)j--;
        }
        return false;
    }
    /*
    下旗
     */
    public int playChess(char[][]board,int x,int y){


        if (canInput(board,x,y)==true)
            board[x][y] = '0'; //将白子落在这个位置
        //棋盘的展现
        showBoard(board);
            /*
            判断五子成龙
             */
        if(judgeSuccess(board,x,y,'0')==true) {
            System.out.println("白棋获胜");
            return '0';
        }
        /*
        黑棋落子 黑棋用1表示
         */
        System.out.println("请输入你要落黑子的位置：");
        Boolean a = AI(board); //ai落子
        //棋盘的展现
        showBoard(board);
        if (a == true){
            System.out.println("黑棋获胜");
            return '1';}


        return 'e';
    }
    /*
    判断位置是否为空
     */
    public boolean canInput(char[][] board,int x,int y){
        if (board[x][y]=='+'){
            return true;
        } else return false;
    }

    /*
    评分估测
     */
    //米字型搜索
    //[—, | , / , \]四个移动方向
    static int inX[] = { 1,0,1,1 };
    static int inY[] = { 0,1,1,-1 };
    public int getScore(char[][] board,int x,int y,char color){
        //返回评分值
        int re = 0;

        //向 [—,|, /, \]四个方向搜索，对应inX，inY
        for (int i = 0; i < 4; ++i) {
            //k记录连子两侧空位的数目（非墙，非敌方落子）
            int k = 0;
            //记录连子的数目，初始值为1因为假设在当前位置落子
            int count = 1;

            //[—,|, /, \]四个方向的正负方向
            for (int j = -1; j < 2; j += 2) {
                int dx = x + j * inX[i];
                int dy = y + j * inY[i];

                //判断是否超出棋盘边界
                while (dx >= 0 && dx < board.length &&
                        dy >= 0 && dy < board.length) {
                    //假如遇到颜色相同的子，count+1，反之则退出循环，并判断此时有无空位
                    if (board[dx][dy]==color) {
                        ++count;
                    }
                    else {
                        if (board[dx][dy]== '+') ++k;
                        break;
                    }

                    dx += j * inX[i];
                    dy += j * inY[i];
                }
            }

            //假如连子大于5，使之等于5
            if (count > 5) count = 5;

            //加上该方向所得评分
            re += score[k][count];
        }

        return re;
    }
    /*
    智障小电脑
     */
    public boolean AI(char[][] board){
        int Beta = 0;
        int Alpha = 100000000;
        int max =  0;
        int min =  100000000;
        ArrayList<Integer> X = new ArrayList<>();
        ArrayList<Integer> Y = new ArrayList<>();
        //遍历棋盘
        for (int i = 0; i < board.length; ++i) {
            for (int j = 0; j < board.length; ++j) {
                //判断是否为空位
                if (board[i][j] == '+') {
                    Chess chess = new Chess(i,j,'1'); //创建一个黑棋对象
                    maxminNode node = new maxminNode(chess);
                    node.setCore(board);
                    char[][] core = node.getCore();
                    core[i][j] = '1';
                    root = node;
                    tt:
                    for (int i2 = 0; i2 < board.length; ++i2) {
                        for (int j2 = 0; j2 < board.length; ++j2) {
                            if (core[i2][j2] == '+'){
                                Chess chess1 = new Chess(i,j,'0');//创建一个白棋对象
                                maxminNode node1 = new maxminNode(chess1);
                                node.setNext(node1);
                                int score = getScore(core,i2,j2,'0');
                                if (score>Alpha) break tt;
                                if (score >= max){
                                    max = score;
                                    Beta = max;   //将白棋获得的最大评分赋值给Beta
                                }
                            }
                        }
                        }
                    if (Beta<Alpha){
                      Alpha = Beta;
                    }
                      if (max <= min){
                          X.clear();
                          Y.clear();
                           min = max;
                      }
                      X.add(i);
                      Y.add(j);
                }
            }
        }
        //在最大值中任取一个返回,大部分情况只有一个
        Random r = new Random(X.size());
        int rr = r.nextInt(X.size());
        int x = X.get(rr);
        int y = Y.get(rr);
        if (board[x][y]=='+'){
            board[x][y] = '1'; //将黑子落在这个位置
        }
        return judgeSuccess(board,x,y,'1');

    }

}
